//*****************************************************************************
// JFab (http://code.google.com/p/jfab)
// Copyright (c) 2011-2012 JFab.org
// Admin jfab@jeffreythompson.net
//
// See the file "LICENSE.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//*****************************************************************************

package org.jfab.swingui.editpane;

import java.util.List;

import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.jfab.core.adapter.Adapter;
import org.jfab.core.adapter.CGAnnotationAdapter;
import org.jfab.core.adapter.CGTypeAdapter;
import org.jfab.core.adapter.ListAdapter;
import org.jfab.core.model.CGAnnotation;
import org.jfab.core.model.CGObject;
import org.jfab.core.model.CGType;

/**
 * Provide an edit pane for a code generator object.
 * 
 * @param <T> Subject type.
 */
public class CGObjectEditPane<T extends CGObject> extends AbstractEditPane<T>
{
    /** Serial version UID. */
    private static final long serialVersionUID = 1L;

    /** Annotations widget. */
    protected JTextArea _annotationsUI;

    /** CGAnnotation adapter. */
    private Adapter<CGAnnotation> _cgAnnotationAdapter;

    /** List&lt;CGAnnotation&gt; adapter. */
    private Adapter<List<CGAnnotation>> _cgAnnotationListAdapter;

    /** CGType adapter. */
    private Adapter<CGType> _cgTypeAdapter;

    /** List&lt;CGType&gt; adapter. */
    private Adapter<List<CGType>> _cgTypeListAdapter;

    /** Class widget. */
    protected JLabel _classUI;

    /** Comment lines widget. */
    protected JTextArea _commentLinesUI;

    /** Modifiers widget. */
    protected JTextArea _modifiersUI;

    /** Name widget. */
    protected JTextField _nameUI;

    /** Referenced types widget. */
    protected JTextArea _referencedTypesUI;

    /** Title widget. */
    protected JLabel _titleUI;

    /**
     * Construct this object with the given parameter.
     * 
     * @param cgObject Code generator object.
     */
    public CGObjectEditPane(final T cgObject)
    {
        super(cgObject);
    }

    @Override
    public void applyChanges()
    {
        final CGObject subject = getSubjectObject();

        subject.getReferencedTypes().clear();
        subject.getReferencedTypes().addAll(
                getCgTypeListAdapter().unmarshal(_referencedTypesUI.getText()));

        subject.getCommentLines().clear();
        subject.getCommentLines().addAll(
                getStringListAdapter().unmarshal(_commentLinesUI.getText()));

        subject.getAnnotations().clear();
        subject.getAnnotations().addAll(
                getCgAnnotationListAdapter()
                        .unmarshal(_annotationsUI.getText()));

        subject.getModifiers().clear();
        subject.getModifiers().addAll(
                getStringListAdapter().unmarshal(_modifiersUI.getText()));

        subject.setName(_nameUI.getText());

        super.applyChanges();
    }

    @Override
    protected void createWidgets()
    {
        _annotationsUI = createTextArea();
        _classUI = createLabel();
        _commentLinesUI = createTextArea();
        _modifiersUI = createTextArea();
        _nameUI = createTextField();
        _referencedTypesUI = createTextArea();
        _titleUI = createLabel();
    }

    @Override
    protected void fillPanel()
    {
        bindAndAdd("title", _titleUI);
        bindAndAdd("class", _classUI);
        bindAndAdd("referencedTypes", _referencedTypesUI,
                getCgTypeListAdapter());
        bindAndAdd("commentLines", _commentLinesUI, getStringListAdapter());
        bindAndAdd("annotations", _annotationsUI, getCgAnnotationListAdapter());
        bindAndAdd("modifiers", _modifiersUI, getStringListAdapter());
        bindAndAdd("name", _nameUI);
    }

    @Override
    protected void fillWidgets()
    {
        final CGObject subject = getSubjectObject();

        _titleUI.setText(getClass().getSimpleName());
        _classUI.setText(subject.getClass().getName());
        _referencedTypesUI.setText(getCgTypeListAdapter().marshal(
                subject.getReferencedTypes()));
        _commentLinesUI.setText(getStringListAdapter().marshal(
                subject.getCommentLines()));
        _annotationsUI.setText(getCgAnnotationListAdapter().marshal(
                subject.getAnnotations()));
        _modifiersUI.setText(getStringListAdapter().marshal(
                subject.getModifiers()));
        _nameUI.setText(subject.getName());
    }

    /**
     * @return the cgAnnotationAdapter
     */
    protected Adapter<CGAnnotation> getCgAnnotationAdapter()
    {
        if (_cgAnnotationAdapter == null)
        {
            _cgAnnotationAdapter = new CGAnnotationAdapter(getCgTypeAdapter());
        }

        return _cgAnnotationAdapter;
    }

    /**
     * @return the cgAnnotationListAdapter
     */
    protected Adapter<List<CGAnnotation>> getCgAnnotationListAdapter()
    {
        if (_cgAnnotationListAdapter == null)
        {
            _cgAnnotationListAdapter = new ListAdapter<CGAnnotation>(
                    getCgAnnotationAdapter());
        }

        return _cgAnnotationListAdapter;
    }

    /**
     * @return the cgTypeAdapter
     */
    protected Adapter<CGType> getCgTypeAdapter()
    {
        if (_cgTypeAdapter == null)
        {
            _cgTypeAdapter = new CGTypeAdapter();
        }

        return _cgTypeAdapter;
    }

    /**
     * @return the cgTypeListAdapter
     */
    protected Adapter<List<CGType>> getCgTypeListAdapter()
    {
        if (_cgTypeListAdapter == null)
        {
            _cgTypeListAdapter = new ListAdapter<CGType>(getCgTypeAdapter());
        }

        return _cgTypeListAdapter;
    }
}
